﻿using EmprestaAE.Common;
using EmprestaAE.MVVM.Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.ApplicationModel.Contacts;
using Windows.ApplicationModel.Core;
using Windows.Media.Capture;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media.Imaging;

namespace EmprestaAE.MVVM.ViewModel
{
    class LendVM : ViewModelBase
    {

        #region Singleton
        private static LendVM instance;

        public static LendVM Instance
        {
            get { return instance ?? (instance = new LendVM()); }
        }
        #endregion

        private VMCommand selectContactCommand;

        public VMCommand SelectContactCommand
        {
            get { return selectContactCommand ?? (selectContactCommand = new VMCommand(SelectContactCommandAction)); }
        }

        private async void SelectContactCommandAction(object param)
        {

            ContactPicker picker = new ContactPicker();
            ContactInformation contact = await picker.PickSingleContactAsync();

            if (contact != null)
            {
                using (IRandomAccessStreamWithContentType stream = await contact.GetThumbnailAsync())
                {
                    if (stream != null && stream.Size > 0)
                    {
                        BitmapImage bitmapimage = new BitmapImage();
                        bitmapimage.SetSource(stream);
                        this.ContactImage = new Image() { Source = bitmapimage };                        
                        ContactName = contact.Name;
                        ContactImagePickered = true;


                        var reader = new DataReader(stream.GetInputStreamAt(0));
                        var data = new byte[stream.Size];
                        await reader.LoadAsync((uint)stream.Size);
                        reader.ReadBytes(data);
                        ContactImageStream = data;
                    }
                }
            }
        }

        private byte[] contactImageStream;

        public byte[] ContactImageStream
        {
            get { return contactImageStream; }
            set { contactImageStream = value; }
        }

        private byte[] whatImageStream;

        public byte[] WhatImageStream
        {
            get { return whatImageStream; }
            set { whatImageStream = value; }
        }
        
        

        private VMCommand lendCommand;

        public VMCommand LendCommand
        {
            get { return lendCommand ?? (lendCommand = new VMCommand(LendCommandAction)); }
            set { lendCommand = value; }
        }

        private void LendCommandAction(object param)
        {
            Person = new Person() { Name = ContactName, ImageStream = ContactImageStream };
            Thing = new Thing() { ImageStream = WhatImageStream };
            Lending = new Lending() { ID = 1, Status = false, Person = Person, Thing = Thing, Until = Date, When = When };
            MainVM.Instance.AddLendingCommand.Execute(Lending);
            NavigationService.GoBackCommand.Execute(param);
        }

        private Lending lending;

        public Lending Lending
        {
            get { return lending ?? (lending = new Lending()); }
            set { if (lending != value) { lending = value; RaisePropertyChanged("Lending"); } }
        }

        private DateModel when;

        public DateModel When
        {
            get { return new DateModel() { Date = DateTime.Now.ToLocalTime() }; }
            set { if (when != value) { when = value; RaisePropertyChanged("When"); } }
        }


        private Thing thing;

        public Thing Thing
        {
            get { return thing ?? (thing = new Thing()); }
            set { if (thing != value) thing = value; RaisePropertyChanged("Thing"); }
        }


        private Person person;

        public Person Person
        {
            get { return person ?? (person = new Person()); }
            set { if (person != value) person = value; RaisePropertyChanged("Person"); }
        }

        private Image contactImage;

        public Image ContactImage
        {
            get { return contactImage ?? (contactImage = new Image()); }
            set { if (contactImage != value) { contactImage = value; RaisePropertyChanged("ContactImage"); } }
        }

        private Image whatImage;

        public Image WhatImage
        {
            get { return whatImage ?? (whatImage = new Image()); }
            set { if (whatImage != value) { whatImage = value; RaisePropertyChanged("WhatImage"); } }
        }

        private string contactName;

        public string ContactName
        {
            get { return contactName; }
            set { if (contactName != value) { contactName = value; RaisePropertyChanged("ContactName"); } }
        }

        private bool datePickered;

        public bool DatePickered
        {
            get { return datePickered; }
            set { if (datePickered != value) { datePickered = value; RaisePropertyChanged("DatePickered"); } }
        }

        private bool whatImagePickered;

        public bool WhatImagePickered
        {
            get { return whatImagePickered; }
            set { if (whatImagePickered != value) { whatImagePickered = value; RaisePropertyChanged("WhatImagePickered"); } }
        }

        private bool contactImagePickered;

        public bool ContactImagePickered
        {
            get { return contactImagePickered; }
            set { if (contactImagePickered != value) { contactImagePickered = value; RaisePropertyChanged("ContactImagePickered"); } }
        }

        private bool lendEnable;

        public bool LendEnable
        {
            get { return lendEnable; }
            set { if (lendEnable != value) { lendEnable = value; RaisePropertyChanged("LendEnable"); } }
        }

        private DateModel date;

        public DateModel Date
        {
            get { return date; }
            set { if (date != value) { date = value; RaisePropertyChanged("Date"); } }
        }


        private VMCommand captureWhatCommand;

        public VMCommand CaptureWhatCommand
        {
            get { return captureWhatCommand ?? (captureWhatCommand = new VMCommand(CaptureWhatCommandAction)); }
        }        
        
        private async void CaptureWhatCommandAction(object param)
        {           

            var dialog = new CameraCaptureUI();
            dialog.PhotoSettings.AllowCropping = true;
            StorageFile file = await dialog.CaptureFileAsync(CameraCaptureUIMode.Photo);

            if (file != null)
            {
                IRandomAccessStream stream = await file.OpenAsync(FileAccessMode.Read);
                var reader = new DataReader(stream.GetInputStreamAt(0));
                var data = new byte[stream.Size];
                await reader.LoadAsync((uint)stream.Size);
                reader.ReadBytes(data);
                WhatImageStream = data;


                BitmapImage bitmap = new BitmapImage();
                bitmap.SetSource(stream);
                WhatImage = new Image() { Source = bitmap };                
            }
        }



        private bool isWhatInputing;

        public bool IsWhatInputing
        {
            get { return isWhatInputing; }
            set { if (isWhatInputing != value) { isWhatInputing = value; RaisePropertyChanged("IsWhatInputing"); } }
        }

        private VMCommand activateWhatInputCommand;

        public VMCommand ActivateWhatInputCommand
        {
            get { return activateWhatInputCommand ?? (activateWhatInputCommand = new VMCommand(ActivateWhatInputCommandAction)); }
            
        }

        private void ActivateDeactivateInput(string activeInput)
        {
            switch (activeInput)
            {
                case "WhatInput":
                    IsWhatInputing = true;
                    IsPersonInputing = false;
                    IsUntilInputing = false;
                    break;
                case "PersonInput":
                    IsWhatInputing = false;
                    IsPersonInputing = true;
                    IsUntilInputing = false;
                    break;
                case "UntilInput":
                    IsWhatInputing = false;
                    IsPersonInputing = false;
                    IsUntilInputing = true;
                    break;
                default:
                    break;
            }
        }

        private void ActivateWhatInputCommandAction(object obj)
        {
            ActivateDeactivateInput(obj.ToString());
        }

        private bool isPersonInputing;

        public bool IsPersonInputing
        {
            get { return isPersonInputing; }
            set { if (isPersonInputing != value) { isPersonInputing = value; RaisePropertyChanged("IsPersonInputing"); } }
        }

        private VMCommand activatePersonInputCommand;

        public VMCommand ActivatePersonInputCommand
        {
            get { return activatePersonInputCommand ?? (activatePersonInputCommand = new VMCommand(ActivatePersonInputCommandAction)); }            
        }

        private void ActivatePersonInputCommandAction(object obj)
        {
            ActivateDeactivateInput(obj.ToString());
        }

        private bool isUntilInputing;

        public bool IsUntilInputing
        {
            get { return isUntilInputing; }
            set { if (isUntilInputing != value) { isUntilInputing = value; RaisePropertyChanged("IsUntilInputing"); } }
        }

        private VMCommand activateUntilInputCommand;

        public VMCommand ActivateUntilInputCommand
        {
            get { return activateUntilInputCommand ??(activateUntilInputCommand = new VMCommand(ActivateUntilInputCommandAction)); }
            
        }

        private void ActivateUntilInputCommandAction(object obj)
        {
            ActivateDeactivateInput(obj.ToString());
        }

        public LendVM()
        {
            PropertyChanged += LendVM_PropertyChanged;
            DatePickerVM.Instance.DatePickeredChanged += DatePickerVM_DatePickeredChanged;
        }

        void LendVM_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "ContactImage":
                    ContactImagePickered = true;
                    break;
                case "WhatImage":
                    WhatImagePickered = true;
                    break;
                case "Date":
                    DatePickered = true;
                    break;
                default:
                    break;
            }

            TryEnableLend();
        }

        private void DatePickerVM_DatePickeredChanged()
        {
            Date = new DateModel() { Date = DatePickerVM.Instance.Date.Date };
            DatePickered = true;
        }

        private void TryEnableLend()
        {
            if (WhatImagePickered && DatePickered && ContactImagePickered)
            {
                LendEnable = true;
            }
            else
            {
                LendEnable = false;
            }
        }

    }
}
